package com.lancoo.dictionary.widget;

import android.content.Context;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaPlayer;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.lancoo.dictionary.DictionaryHelper;
import com.lancoo.dictionary.R;
import com.lancoo.dictionary.activity.DictionaryActicity;
import com.lancoo.dictionary.data.model.DicSearchBehavior;
import com.lancoo.dictionary.data.model.Meaning;
import com.lancoo.dictionary.data.model.Paraphrase;
import com.lancoo.dictionary.data.model.SearchHistory;
import com.lancoo.dictionary.data.model.Vocabulary;
import com.lancoo.dictionary.nc.NetworkConnection;

import org.xutils.DbManager;
import org.xutils.common.Callback;
import org.xutils.ex.DbException;

import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * by Terence,Kemp.
 */
public class DictionaryPop extends PopupWindow implements View.OnClickListener {

    private TextView mTvUs, mTvUn, mTvExplainOne;
    private Button mBtQuerryAll;
    private ProgressBar mPbLoading;
    private LinearLayout rootView;
    private ImageView trianglePositive;
    private ImageView triangleNegative;

    private Vocabulary mVocabulary;
    private Context mContext;

    private int mPopHeight, mPopWidth;
    private String mCurrentText;
    private MediaPlayer mediaPlayer;

    public static final int STYLE_SHOW_UP = 0X100;
    public static final int STYLE_SHOW_CENTER = 0X101;
    public static final int STYLE_SHOW_EXACTLY = 0X102;

    private OnPlayDictionaryListener mListener;

    public DictionaryPop(Context context, int width, int height) {
        super(context);
        mContext = context;
        View view = LayoutInflater.from(context).inflate(R.layout.lcdic_layout_dictionary_pop, null);
        setContentView(view);
        initView(view);
        initEvent();
        setWidth(width);
        setHeight(height);
        mPopWidth = width;
        mPopHeight = height;
        setAnimationStyle(R.style.LCDicPopupWindowAnimation);
        setTouchable(true);
        setFocusable(true);  //slove isShowing always return false
        setOutsideTouchable(true);
        setBackgroundDrawable(new BitmapDrawable());
        mediaPlayer = new MediaPlayer();
    }

    private void initEvent() {
        mTvUn.setOnClickListener(this);
        mTvUs.setOnClickListener(this);
        mBtQuerryAll.setOnClickListener(this);
    }

    private void initView(View view) {
        mTvUn = (TextView) view.findViewById(R.id.tv_un_voice);
        mTvUs = (TextView) view.findViewById(R.id.tv_us_voice);
        mTvExplainOne = (TextView) view.findViewById(R.id.tv_explain_one);
        rootView = (LinearLayout) view.findViewById(R.id.root_dictionary_pop);
        trianglePositive = (ImageView) view.findViewById(R.id.dic_pop_triangle_positive);
        triangleNegative = (ImageView) view.findViewById(R.id.dic_pop_triangle_negative);

        mBtQuerryAll = (Button) view.findViewById(R.id.bt_query_all);
        mPbLoading = (ProgressBar) view.findViewById(R.id.pb_loading);
    }

    int[] location = new int[2];

    private void showUp(View view) {
        if (isShowing()) {
            dismiss();
        }
        view.getLocationOnScreen(location);
        showAtLocation(view, Gravity.NO_GRAVITY, (location[0] + view.getWidth() / 2) - mPopWidth / 2,
                location[1] - mPopHeight);
    }

    private void showInCenter(View parent) {
        showAtLocation(parent, Gravity.CENTER, 0, 0);
    }

    private void showExactly(View parent, int x, int y) {
        Log.e("child", "click-x:" + x + "click-y:" + y);
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        Point screenSize = new Point();
        wm.getDefaultDisplay().getSize(screenSize);
        int maxWidth = screenSize.x;
        int maxHeight = screenSize.y;
        parent.getLocationOnScreen(location);
        getContentView().measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED);
        int finalX;

        if (x-getContentView().getMeasuredWidth()/2<0){
            rootView.setGravity(Gravity.START);
            finalX =x;
        }else if(x+getContentView().getMeasuredWidth()/2>maxWidth){
            rootView.setGravity(Gravity.END);
            finalX= x-getContentView().getMeasuredWidth();
        }else{
            rootView.setGravity(Gravity.CENTER_HORIZONTAL);
            finalX =x-getContentView().getMeasuredWidth()/2;
        }
//        int xCenter = (location[0]+parent.getWidth())/2+(parent.getPaddingLeft()-parent.getPaddingRight())/2;
//        int leftborder = xCenter-getContentView().getMeasuredWidth()/2;
//        Log.e("fuckCenter","center:"+leftborder);
//        int rightborder = xCenter+getContentView().getMeasuredWidth()/2;

        if (y + getContentView().getMeasuredHeight() > maxHeight) {
            trianglePositive.setVisibility(View.GONE);
            triangleNegative.setVisibility(View.VISIBLE);
            showAtLocation(parent, Gravity.NO_GRAVITY, finalX, y-getContentView().getMeasuredHeight());
        } else {
            trianglePositive.setVisibility(View.VISIBLE);
            triangleNegative.setVisibility(View.GONE);
            showAtLocation(parent, Gravity.NO_GRAVITY, finalX, y);
        }
    }

    @Override
    public void onClick(View v) {
        if (mVocabulary == null) return;
        int id = v.getId();
        if (id == R.id.tv_un_voice) {
            playSound(DictionaryHelper.RES_BASE_URL + mVocabulary.getUnPVoice());

        } else if (id == R.id.tv_us_voice) {
            playSound(DictionaryHelper.RES_BASE_URL + mVocabulary.getUsPVoice());

        } else if (id == R.id.bt_query_all) {
            if (!TextUtils.isEmpty(mCurrentText)) {
                DictionaryActicity.startWithContent(mContext, mCurrentText);
            }
            dismiss();
        }
    }

    @Override
    public void setOnDismissListener(OnDismissListener onDismissListener) {
        super.setOnDismissListener(onDismissListener);
//        if (mediaPlayer != null) {
//            mediaPlayer.stop();
//        }
        releasePlayer();
    }

    public interface OnPlayDictionaryListener {
        void play();

        void done();
    }

    private void playSound(String voice) {

        try {
            if (mediaPlayer != null) {
                if (mListener != null) {
                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            mListener.done();
                        }
                    });
                }
                mediaPlayer.reset();
                mediaPlayer.setDataSource(voice);
                mediaPlayer.prepare();
                mediaPlayer.start();
                if (mListener != null) {
                    mListener.play();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void releasePlayer() {
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    private void setData(Vocabulary vocabulary) {
        if (vocabulary == null) return;
        mVocabulary = vocabulary;
        String unPText = vocabulary.getUnPText();
        mTvUn.setText((TextUtils.isEmpty(unPText) ? "无英式音标" : "英 " + Html.fromHtml(unPText)));
        String usPText = vocabulary.getUsPText();
        mTvUs.setText((TextUtils.isEmpty(usPText) ? "无美式音标" : "美 " + Html.fromHtml(usPText)));
        setChineseMeaning(vocabulary);
    }

    private void setChineseMeaning(Vocabulary vocabulary) {
        StringBuilder cBuilder = new StringBuilder();
        List<Paraphrase> paraphrases = vocabulary.getCxCollection();
        for (int i = 0; i < paraphrases.size(); i++) {
            Paraphrase paraphrase = paraphrases.get(i);
            String cp = paraphrase.getCxChinese();
            if (!TextUtils.isEmpty(cp)) {
                cBuilder.append(cp).append('。');
            }
            List<Meaning> meanings = paraphrase.getMeanCollection();
            if (meanings == null) {
                continue;
            }
            for (int j = 0; j < meanings.size(); j++) {
                Meaning meaning = meanings.get(j);
                cBuilder.append(Html.fromHtml(meaning.getChineseMeaning()));
                if (j < meanings.size() - 1) {
                    cBuilder.append('；');
                }
            }
            if (i < paraphrases.size() - 1) {
                cBuilder.append('\n');
            }
        }
        mTvExplainOne.setText(cBuilder);
    }

    public void queryData(final String text, final View view, final int showLocation, OnPlayDictionaryListener listener, final int x, final int y) {
        mListener = listener;
        mCurrentText = text;
        mPbLoading.setVisibility(View.VISIBLE);

        final DbManager dbManager = DictionaryHelper.getDbManager();
        try {
            SearchHistory searchHistory = dbManager == null ? null : dbManager.findById(SearchHistory.class, text);
            if (searchHistory != null) {
                Vocabulary vocabulary = new Gson().fromJson(searchHistory.getMeaning(), Vocabulary.class);
                setData(vocabulary);
                showByArg(showLocation, view, x, y);
                DictionaryHelper.sendDicSearchBroadcast(mContext, vocabulary.getCwName(), DicSearchBehavior.SOURCE_DB, true);
                mPbLoading.setVisibility(View.GONE);
                return;
            }
        } catch (DbException e) {
            e.printStackTrace();
        }


        new NetworkConnection(text, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String s) {
                Vocabulary vocabulary = new Gson().fromJson(s, new TypeToken<Vocabulary>() {
                }.getType());
                if (vocabulary == null) {
                    Toast.makeText(mContext, R.string.lcdic_search_failed, Toast.LENGTH_SHORT).show();
                    DictionaryHelper.sendDicSearchBroadcast(mContext, text, DicSearchBehavior.SOURCE_HTTP, false);
                } else {
                    setData(vocabulary);
                    showByArg(showLocation, view, x, y);
                    try {
                        if (dbManager != null) {
                            dbManager.saveOrUpdate(new SearchHistory(vocabulary.getCwName(), new Date(), s));
                        }
                    } catch (DbException e) {
                        e.printStackTrace();
                    } finally {
                        DictionaryHelper.sendDicSearchBroadcast(mContext, text, DicSearchBehavior.SOURCE_HTTP, true);
                    }
                }
            }

            @Override
            public void onError(Throwable throwable, boolean b) {
                Toast.makeText(mContext, R.string.lcdic_fetch_data_failed, Toast.LENGTH_SHORT).show();
                DictionaryHelper.sendDicSearchBroadcast(mContext, text, DicSearchBehavior.SOURCE_HTTP, false);
            }

            @Override
            public void onCancelled(CancelledException e) {

            }

            @Override
            public void onFinished() {
                mPbLoading.setVisibility(View.GONE);
            }
        });
    }

    private void showByArg(int showLocationStyle, View view, int x, int y) {
        if (showLocationStyle == STYLE_SHOW_CENTER) {
            showInCenter(view);
        }
        if (showLocationStyle == STYLE_SHOW_UP) {
            showUp(view);
        }
        if (showLocationStyle == STYLE_SHOW_EXACTLY) {
            showExactly(view, x, y);
        }
    }


    public static void showCenterInParent(String searchWord, View parent) {
        DictionaryPop dictionaryPop = new DictionaryPop(parent.getContext(), ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        dictionaryPop.queryData(searchWord, parent, STYLE_SHOW_CENTER, null, -1, -1);
    }

    public static void showAboveToTarget(String searchWord, View target) {
        DictionaryPop dictionaryPop = new DictionaryPop(target.getContext(), ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        dictionaryPop.queryData(searchWord, target, STYLE_SHOW_UP, null, -1, -1);
    }

    public static void showExactlyInParent(String searchWord, View parent, int x, int y) {
        DictionaryPop dictionaryPop = new DictionaryPop(parent.getContext(), ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        dictionaryPop.queryData(searchWord, parent, STYLE_SHOW_EXACTLY, null, x, y);
    }
}
